/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Formulario.java
 *
 * Created on 28/05/2011, 22:11:24
 */
package app.view;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;

import javax.swing.ImageIcon;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

import app.controller.ChequeController;
import app.exceptions.DataInvalidaException;
import app.exceptions.TaxaInvalidaException;
import app.exceptions.ValorInvalidoException;
import app.model.Cheque;

public class Formulario extends javax.swing.JFrame {

	private static final long serialVersionUID = 1L;
	
	/** Creates new form Formulario */
	public Formulario() {

		initComponents();

		setIconImage(new ImageIcon(getClass().getResource(
				"/app/resources/factoring.jpg")).getImage());

		ChequeController.load();

		carregaControlador(ChequeController.getInstance());

		textTaxa.setText(String.valueOf(ChequeController.getInstance()
				.getTaxaJuros()));

		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		setBounds(dim.width / 2 - getWidth() / 2, dim.height / 2 - getHeight()
				/ 2, getWidth(), getHeight());
		
		
		DataCellEditor dce = new DataCellEditor();
		
		dce.addListener(new EditingFinishedListener() {
			
			@Override
			public void trigger() {
				terminouEdicao();
			}
		});
		
		TextCellEditor tce = new TextCellEditor();
		
		tce.addListener(new EditingFinishedListener() {
			
			@Override
			public void trigger() {
				terminouEdicao();
				
			}
		});
		
		tabela.getColumnModel().getColumn(0)
		.setCellEditor(tce);
		
		tabela.getColumnModel().getColumn(3)
		.setCellEditor(tce);
		
		tabela.getColumnModel().getColumn(1)
				.setCellEditor(dce);

		tabela.getColumnModel().getColumn(2)
				.setCellEditor(dce);

		tabela.getColumnModel().getColumn(1).setPreferredWidth(100);

		tabela.getColumnModel().getColumn(2).setPreferredWidth(120);

		setTableCellAlignment();
		
		statusMessage.setText("Factoring");
		
	}
	
	public void resetaMensagem() {
		Thread messageReseter = new Thread(new Runnable() {
			
			@Override
			public void run() {
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				statusMessage.setText("Factoring");
				
			}
		});
		
		messageReseter.start();
	}
	
	private void deselecionaBotoes() {
		statusMessage.requestFocus();
	}

	protected void terminouEdicao() {
		int COLUNA_ATUAL = tabela.getSelectedColumn();
		int LINHA_ATUAL = tabela.getSelectedRow();
		
		tabela.setColumnSelectionInterval(COLUNA_ATUAL + 1, COLUNA_ATUAL + 1);
		tabela.setRowSelectionInterval(LINHA_ATUAL, LINHA_ATUAL);
		
		tabela.editCellAt(LINHA_ATUAL, COLUNA_ATUAL + 1);

		Component myEditor = tabela.getEditorComponent();

		if (myEditor != null)
			myEditor.requestFocus();
	}

	private void setTableCellAlignment() {

		DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
		renderer.setHorizontalAlignment(SwingConstants.CENTER);
		for (int i = 0; i < tabela.getColumnCount() - 1; i++) {
			tabela.setDefaultRenderer(tabela.getColumnClass(i), renderer);
		}

		// repaint to show table cell changes
		tabela.updateUI();
	}

	private void carregaControlador(ChequeController cc) {

		DefaultTableModel dtm = (DefaultTableModel) tabela.getModel();
		SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");

		for (Cheque c : cc.getList())
			if (c == null)
				dtm.addRow(new Object[] { null, null, null, null, null, null,
						null, true });
			else
				dtm.addRow(new Object[] {
						c.getNome(),
						formatter.format(c.getDataInicial().getTime()),
						formatter.format(c.getDataVencimento().getTime()),
						String.valueOf(c.getValor()).replace(".", ","),
						c.getBanco(),
						"R$ "
								+ String.valueOf(
										Math.round(c.calculaValorNoVencimento() * 100.0) / 100.0)
										.replace(".", ","), c.getDiffDias(),
						true });
	}

	public void escondeBarraInferior() {
		labelTotalValorInicial.setVisible(false);
		labelTotalValorFinal.setVisible(false);
		textTotalValorInicial.setVisible(false);
		textTotalValorFinal.setVisible(false);
	}

	public void apareceBarraInferior() {
		labelTotalValorInicial.setVisible(true);
		labelTotalValorFinal.setVisible(true);
		textTotalValorInicial.setVisible(true);
		textTotalValorFinal.setVisible(true);
	}

	public void atualizaTabela() {

		final int NOME = 0;
		final int DATA_EMISSAO = 1;
		final int DATA_VENC = 2;
		final int VALOR_INI = 3;
		final int BANCO = 4;
		final int VALOR_FIM = 5; // Nao Editavel
		final int DIAS = 6; // Nao Editavel
		final int MANTER = 7; // Nao Editavel

		double totalInicial = 0;
		double totalFinal = 0;
		
		// Se tiver a ultima linha completa
		
		int LAST_ROW = tabela.getRowCount() - 1;
		
		if (LAST_ROW == -1 || !(tabela.getValueAt(LAST_ROW, NOME) == null
				|| tabela.getValueAt(LAST_ROW, DATA_VENC) == null
				|| tabela.getValueAt(LAST_ROW, DATA_EMISSAO) == null
				|| tabela.getValueAt(LAST_ROW, VALOR_INI) == null)) {

			botaoNovaLinhaActionPerformed(null);
		}
		
		try {

			try {
				ChequeController.getInstance().setTaxa(
						Double.valueOf(textTaxa.getText().replace(",", ".")));

			} catch (Exception e) {
				throw new TaxaInvalidaException(textTaxa.getText());
			}

			for (int x = 0; x < tabela.getRowCount(); x++) {

				if (!((Boolean) tabela.getValueAt(x, MANTER))) {
					((DefaultTableModel) tabela.getModel()).removeRow(x);
					ChequeController.getInstance().muda(x, null);
					x--;
					continue;
				}

				// Se Linha tiver campos incompletos, pula
				if (tabela.getValueAt(x, NOME) == null
						|| tabela.getValueAt(x, DATA_VENC) == null
						|| tabela.getValueAt(x, DATA_EMISSAO) == null
						|| tabela.getValueAt(x, VALOR_INI) == null) {

					continue;
				}

				float valorReferencia;

				try {
					valorReferencia = Float.parseFloat(((String) tabela
							.getValueAt(x, VALOR_INI)).replace(".", "")
							.replace(",", "."));
				} catch (Exception e) {

					throw new ValorInvalidoException(
							(String) tabela.getValueAt(x, VALOR_INI));
				}

				GregorianCalendar dataEmissao;

				try {

					String[] dataIniDiv = (((String) (tabela.getValueAt(x,
							DATA_EMISSAO))).replace(".", "/").replace(" ", "/"))
							.split("/");

					dataEmissao = new GregorianCalendar(
							Integer.valueOf(dataIniDiv[2]),
							Integer.valueOf(dataIniDiv[1]) - 1,
							Integer.valueOf(dataIniDiv[0]));

				} catch (Exception e) {

					throw new DataInvalidaException(
							(String) (tabela.getValueAt(x, DATA_EMISSAO)));

				}

				GregorianCalendar dataVencimento;

				try {

					String[] dataDiv = (((String) (tabela.getValueAt(x,
							DATA_VENC))).replace(".", "/").replace(" ", "/"))
							.split("/");

					dataVencimento = new GregorianCalendar(
							Integer.valueOf(dataDiv[2]),
							Integer.valueOf(dataDiv[1]) - 1,
							Integer.valueOf(dataDiv[0]));

				} catch (Exception e) {
					throw new DataInvalidaException(
							(String) (tabela.getValueAt(x, DATA_VENC)));
				}

				Cheque c = new Cheque((String) tabela.getValueAt(x, NOME),
						valorReferencia, dataEmissao, dataVencimento,
						(String) tabela.getValueAt(x, BANCO));

				ChequeController.getInstance().muda(x, c);

				tabela.getModel()
						.setValueAt(formataValor(c.calculaValorNoVencimento()), x,
								VALOR_FIM);
				totalInicial += c.getValor();
				totalFinal += (Math.round(c.calculaValorNoVencimento() * 100.0) / 100.0);
				tabela.getModel().setValueAt(String.valueOf(c.getDiffDias()),
						x, DIAS);

				tabela.invalidate();
			}
			
			textTotalValorInicial.setText(formataValor(totalInicial));
			textTotalValorFinal.setText(formataValor(totalFinal));
			apareceBarraInferior();

		} catch (TaxaInvalidaException e) {
			escondeBarraInferior();
			statusMessage.setText("Erro na Taxa (" + e.getProblem() + ")");
		} catch (DataInvalidaException e) {
			escondeBarraInferior();
			statusMessage.setText("Erro na Data (" + e.getProblem() + ")");
		} catch (ValorInvalidoException e) {
			escondeBarraInferior();
			statusMessage.setText("Erro no Valor (" + e.getProblem() + ")");
		} catch (Exception e) {
			escondeBarraInferior();
			statusMessage.setText("Erro em local nao especificado (" + e.getMessage() + ")");
			e.printStackTrace();
		}
		
		deselecionaBotoes();

	}

	private String formataValor(double valorDouble) {
		
		valorDouble = (Math.round(valorDouble * 100.0) / 100.0);
		
		String valor = String.valueOf(valorDouble);
		
		valor = valor.replace(".", ",");
		
		char[] valorChars = valor.toCharArray();
		
		boolean comecaContar = false;
		
		int counter = 0;
		
		for (int i = valorChars.length - 1 ; i >= 0 ; i--) {
			if (valorChars[i] == ',') {
				comecaContar = true;
				continue;
			}
			
			if (comecaContar) {
				counter++;
				
				if (counter % 3 == 0 && i - 1 != -1) {
					valor = valor.substring(0, i) + "." + valor.substring(i);
				}
				
			}
			
		}
		return "R$ " + valor;
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
	// <editor-fold defaultstate="collapsed"
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        botaoSalvar = new javax.swing.JButton();
        botaoAtualiza = new javax.swing.JButton();
        statusMessage = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        textTaxa = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        tabela = new javax.swing.JTable();
        jPanel3 = new javax.swing.JPanel();
        labelTotalValorInicial = new javax.swing.JLabel();
        textTotalValorInicial = new javax.swing.JTextField();
        labelTotalValorFinal = new javax.swing.JLabel();
        textTotalValorFinal = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Factoring");
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        setIconImage(Toolkit.getDefaultToolkit().getImage("app/resources/factoring.jpg"));
        setMinimumSize(new java.awt.Dimension(760, 300));
        getContentPane().setLayout(new java.awt.BorderLayout(0, 5));

        jPanel1.setAlignmentX(5.0F);
        jPanel1.setAlignmentY(5.0F);
        jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.LINE_AXIS));

        botaoSalvar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/app/resources/salvar.png"))); // NOI18N
        botaoSalvar.setBorder(null);
        botaoSalvar.setContentAreaFilled(false);
        botaoSalvar.setMaximumSize(new java.awt.Dimension(28, 25));
        botaoSalvar.setMinimumSize(new java.awt.Dimension(28, 25));
        botaoSalvar.setPreferredSize(new java.awt.Dimension(28, 25));
        botaoSalvar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botaoSalvarActionPerformed(evt);
            }
        });
        jPanel1.add(botaoSalvar);

        botaoAtualiza.setIcon(new javax.swing.ImageIcon(getClass().getResource("/app/resources/atualizar.png"))); // NOI18N
        botaoAtualiza.setBorder(null);
        botaoAtualiza.setContentAreaFilled(false);
        botaoAtualiza.setMaximumSize(new java.awt.Dimension(28, 25));
        botaoAtualiza.setMinimumSize(new java.awt.Dimension(28, 25));
        botaoAtualiza.setPreferredSize(new java.awt.Dimension(28, 25));
        botaoAtualiza.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                botaoAtualizaActionPerformed(evt);
            }
        });
        jPanel1.add(botaoAtualiza);

        statusMessage.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        statusMessage.setText("Factoring");
        statusMessage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        statusMessage.setMaximumSize(new java.awt.Dimension(3000, 14));
        statusMessage.setMinimumSize(new java.awt.Dimension(5, 14));
        statusMessage.setPreferredSize(new java.awt.Dimension(10, 14));
        jPanel1.add(statusMessage);

        jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel5.setText("Taxa:");
        jLabel5.setMaximumSize(new java.awt.Dimension(34, 14));
        jLabel5.setMinimumSize(new java.awt.Dimension(34, 14));
        jLabel5.setPreferredSize(new java.awt.Dimension(34, 14));
        jPanel1.add(jLabel5);

        textTaxa.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        textTaxa.setText("0");
        textTaxa.setMaximumSize(new java.awt.Dimension(30, 20));
        textTaxa.setPreferredSize(new java.awt.Dimension(50, 20));
        
        textTaxa.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                textTaxaKeyPressed(evt);
            }
        });
        jPanel1.add(textTaxa);

        jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel6.setText("%");
        jLabel6.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jLabel6.setMaximumSize(new java.awt.Dimension(14, 14));
        jLabel6.setMinimumSize(new java.awt.Dimension(14, 14));
        jLabel6.setPreferredSize(new java.awt.Dimension(14, 14));
        jPanel1.add(jLabel6);

        getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);

        jPanel2.setLayout(new java.awt.GridLayout(1, 0));

        tabela.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Nome", "Data Emissao", "Data de Vencimento", "Valor Inicial", "Banco", "Valor Final", "Dias", "Manter"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Boolean.class
            };
            boolean[] canEdit = new boolean [] {
                true, true, true, true, true, false, false, true
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        tabela.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                tabelaPropertyChange(evt);
            }
        });
        jScrollPane1.setViewportView(tabela);

        jPanel2.add(jScrollPane1);

        getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER);

        jPanel3.setAlignmentX(5.0F);
        jPanel3.setAlignmentY(5.0F);

        labelTotalValorInicial.setText("Total Valor Inicial:");
        jPanel3.add(labelTotalValorInicial);

        textTotalValorInicial.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        textTotalValorInicial.setPreferredSize(new java.awt.Dimension(100, 20));
        textTotalValorInicial.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                textTotalValorInicialKeyPressed(evt);
            }
        });
        jPanel3.add(textTotalValorInicial);
        textTotalValorInicial.getAccessibleContext().setAccessibleParent(textTotalValorInicial);

        labelTotalValorFinal.setText("Total Valor Final:");
        jPanel3.add(labelTotalValorFinal);

        textTotalValorFinal.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        textTotalValorFinal.setPreferredSize(new java.awt.Dimension(100, 20));
        textTotalValorFinal.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                textTotalValorFinalKeyPressed(evt);
            }
        });
        jPanel3.add(textTotalValorFinal);

        getContentPane().add(jPanel3, java.awt.BorderLayout.SOUTH);

        pack();
    }// </editor-fold>//GEN-END:initComponents

	private void tabelaPropertyChange(java.beans.PropertyChangeEvent evt) {// GEN-FIRST:event_tabelaPropertyChange

		atualizaTabela();
	}// GEN-LAST:event_tabelaPropertyChange

	private void botaoNovaLinhaActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_botaoNovaLinhaActionPerformed
		DefaultTableModel dtm = (DefaultTableModel) tabela.getModel();
		dtm.addRow(new Object[] { null, null, null, null, null, null, null,
				true });
	}// GEN-LAST:event_botaoNovaLinhaActionPerformed

	private void botaoAtualizaActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_botaoAtualizaActionPerformed
		
		statusMessage.setText("Tabela Atualizada com Sucesso!");
		atualizaTabela();
		resetaMensagem();
	}// GEN-LAST:event_botaoAtualizaActionPerformed

	private void botaoSalvarActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_botaoSalvarActionPerformed
		
		ChequeController.save();
		
		statusMessage.setText("Salvo com Sucesso!");
		resetaMensagem();

	}// GEN-LAST:event_botaoSalvarActionPerformed

	private void textTaxaKeyPressed(java.awt.event.KeyEvent evt) {// GEN-FIRST:event_textTaxaKeyPressed
	}// GEN-LAST:event_textTaxaKeyPressed

	private void textTotalValorInicialKeyPressed(java.awt.event.KeyEvent evt) {// GEN-FIRST:event_textTotalValorInicialKeyPressed
		// TODO add your handling code here:
	}// GEN-LAST:event_textTotalValorInicialKeyPressed

	private void textTotalValorFinalKeyPressed(java.awt.event.KeyEvent evt) {// GEN-FIRST:event_textTotalValorFinalKeyPressed
		// TODO add your handling code here:
	}// GEN-LAST:event_textTotalValorFinalKeyPressed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton botaoAtualiza;
    private javax.swing.JButton botaoSalvar;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel labelTotalValorFinal;
    private javax.swing.JLabel labelTotalValorInicial;
    private javax.swing.JLabel statusMessage;
    private javax.swing.JTable tabela;
    private javax.swing.JTextField textTaxa;
    private javax.swing.JTextField textTotalValorFinal;
    private javax.swing.JTextField textTotalValorInicial;
    // End of variables declaration//GEN-END:variables
}
